#include <fsnotify.h>
#include <stdio.h>
#include <stdlib.h>

static GString *path_buf;
static GString *path_buf2;

/* Note: under windows, in MinGW's mintty, stdout and stderr become fully-
 * bufferd. The solution is directly set them unbuffered or just use g_print()
 */

void
print_event(struct fsnotify_event *evt)
{
    switch(evt->mask & ~FS_ISDIR) {
    case FS_CREATE:
        dentry_get_path(evt->d.dir, path_buf);
        g_print("FS_CREATE: (inode: %u, path: %s, name: %s)\n",
                evt->d.dir->inode, path_buf->str, evt->name);
        break;
    case FS_DELETE:
        dentry_get_path(evt->d.dir, path_buf);
        g_print("FS_DELETE: (inode: %u, path: %s, name: %s)\n",
                evt->d.dir->inode, path_buf->str, evt->name);
        break;
    case FS_MODIFY:
        dentry_get_path(evt->d.dir, path_buf);
        g_print("FS_MODIFY: (inode: %u, path: %s, name: %s)\n",
                evt->d.dir->inode, path_buf->str, evt->name);
        break;
    case FS_MOVE:
        dentry_get_path(evt->d.rename.from, path_buf);
        dentry_get_path(evt->d.rename.to, path_buf2);
        g_print("FS_MOVE: (inode: %u, from: %s, inode: %u, to: %s, name: %s, "
                "new name: %s)\n",
                evt->d.rename.from->inode, path_buf->str,
                evt->d.rename.to->inode, path_buf2->str,
                evt->name, evt->new_name);
        break;
    case FS_MOVED_FROM:
        dentry_get_path(evt->d.rename.from, path_buf);
        g_print("FS_MOVED_FROM: (inode: %u, from: %s, name: %s)\n",
                        evt->d.rename.from->inode, path_buf->str, evt->name);
        break;
    case FS_MOVED_TO:
        dentry_get_path(evt->d.rename.to, path_buf);
        g_print("FS_MOVED_TO: (inode: %u, from: %s, name: %s)\n",
                        evt->d.rename.to->inode, path_buf->str, evt->name);
        break;
    default:
        g_print("unknown fsnotify_event (mask: %x)\n", evt->mask);
    }
}

int
main(int argc, char *argv[])
{
    char buf[256];
    if (argc != 2) {
        g_print("Usage: fsnotify_test <PATH>\n");
        exit(1);
    }
    int running = 1;

    path_buf = g_string_sized_new(4096);
    path_buf2 = g_string_sized_new(4096);
    fsnotify_register_handler(print_event);
    fsnotify_init_with_path(argv[1]);

    while (running && fgets(buf, sizeof (buf), stdin)) {
        switch (buf[0]) {
        case 'q':
            running = 0;
            break;
        case 'p':
            fsnotify_print_dentry_tree();
            break;
        }
    }

    fsnotify_end();
    g_string_free(path_buf, TRUE);
    g_string_free(path_buf2, TRUE);
    return 0;
}
